from abc import ABC, abstractmethod
from typing import Dict, List


class Item(ABC):
    def __init__(self, name: str, description: str, rarity: str = "common"):
        self._name = name
        self._description = description
        self._rarity = rarity
        self._is_equipped = False
        
        self._attack_bonus = 0
        self._defense_bonus = 0
        self._speed_bonus = 0
        self._health_bonus = 0
        self._mana_bonus = 0
    
    @property
    def name(self) -> str:
        return self._name
    
    @property
    def description(self) -> str:
        return self._description
    
    @property
    def rarity(self) -> str:
        return self._rarity
    
    @property
    def is_equipped(self) -> bool:
        return self._is_equipped
    
    @property
    def attack_bonus(self) -> int:
        return self._attack_bonus
    
    @property
    def defense_bonus(self) -> int:
        return self._defense_bonus
    
    @property
    def speed_bonus(self) -> int:
        return self._speed_bonus
    
    @property
    def health_bonus(self) -> int:
        return self._health_bonus
    
    @property
    def mana_bonus(self) -> int:
        return self._mana_bonus
    
    @abstractmethod
    def get_item_type(self) -> str:
        pass
    
    @abstractmethod
    def get_special_ability(self) -> str:
        pass
    
    def equip(self):
        self._is_equipped = True
    
    def unequip(self):
        self._is_equipped = False
    
    def get_stats(self) -> Dict:
        return {
            "attack": self._attack_bonus,
            "defense": self._defense_bonus,
            "speed": self._speed_bonus,
            "health": self._health_bonus,
            "mana": self._mana_bonus
        }
    
    def get_rarity_color(self) -> str:
        colors = {
            "common": "\033[37m",     
            "uncommon": "\033[32m",  
            "rare": "\033[34m",      
            "epic": "\033[35m",       
            "legendary": "\033[33m"  
        }
        return colors.get(self._rarity, "\033[37m")
    
    def __str__(self) -> str:
        color = self.get_rarity_color()
        reset = "\033[0m"
        return f"{color}[{self.rarity.upper()}]{reset} {self.name}"
    
    def __repr__(self) -> str:
        return f"{self.__class__.__name__}(name='{self.name}', rarity='{self.rarity}')"